#include "clientconnection.h"

ClientConnection::ClientConnection(QHostAddress a, quint16 p, bool onlyReceive) : ConnectionPlayer(a,p,onlyReceive)
{
	connectionHash.clear();
}

ClientConnection::ClientConnection(bool onlyReceive) : ConnectionPlayer(onlyReceive)
{
	connectionHash.clear();
}

void ClientConnection::connectToServer()
{
    if (nick != "")
    {
        connToHost();
        connect(this->timer, SIGNAL(timeout()), this, SLOT(sendState()));
        connect(this,SIGNAL(newPacket(Packet*)),this, SLOT(processPacket(Packet*)));
        PacketData* toSend = new PacketData();
        toSend->appendString("HELLO");
        toSend->appendString(nick);
        sendPacket(toSend,true);
        connectionState = QAbstractSocket::ConnectingState;
        emit connectionStateChanged(connectionState);
    }
}

void ClientConnection::sendState()
{
	if (connectionState == QAbstractSocket::ConnectedState)
	{
		PacketData* toSend = new PacketData();
		toSend->appendString("STATE");
		//toSend->appendInt(getIsAlive());
		if (getIsAlive()) {
			toSend->appendReal(getPos().rx());
			toSend->appendReal(getPos().ry());
			toSend->appendInt(dirs.at(0));
			toSend->appendInt(dirs.at(1));
			toSend->appendInt(getAngle());
			toSend->appendInt(getIsReloading());
		}
		sendPacket(toSend, false, false);
	}

}

void ClientConnection::disconnectFromServer()
{
    PacketData* toSend = new PacketData();
    toSend->appendString("DISCONNECT");
    sendPacket(toSend,false,false);
    connectionHash.clear();
    disconnFromHost();
}

void ClientConnection::sendShootMsg(qreal x, qreal y, qint32 angle)
{
	PacketData* toSend = new PacketData();
	toSend->appendString("SHOOT");
	toSend->appendReal(x);
	toSend->appendReal(y);
	toSend->appendInt(angle);
	//qDebug() << "send shoot msg";
	sendPacket(toSend, true, false);
}

void ClientConnection::runCommand(PacketData* data, bool isNewestPacket)
{
    QString command = data->nextString();
    //if (command == "STATE") qDebug() << "newest packet" << isNewestPacket;
    //qDebug() << "Server says: " <<command;
    if (command == "HELLO") doHELLO(data);
    else if (command == "PING") doPING(data);
    else if (command == "JOIN") doJOIN(data);
    else if (command == "LIST") doLIST(data);
    else if (command == "QUIT") doQUIT(data);
    else if (command == "DISCONNECT") doDISCONNECT(data);
    else if ((command == "STATE") && isNewestPacket) doSTATE(data);
    else if (command == "SHOOT") doSHOOT(data);

    //delete data;
}

void ClientConnection::doHELLO(PacketData* data)
{
    qint32 id = data->nextInt();
    setPlayerId(id);
    setNick(getNick());
    setScore(0);
    /*emit newPlayerConnected(this);*/
    connectionState = QAbstractSocket::ConnectedState;
    startConnectionTimer(true);
    emit connectionStateChanged(connectionState);

}

void ClientConnection::doJOIN(PacketData* data)
{
    qint32 id = data->nextInt();
    QString nick = data->nextString();
    qint32 score = 0;
    ConnectionPlayer* player = new ConnectionPlayer();
    player->setNick(nick);
    player->setScore(score);
    player->setPlayerId(id);
    connectionHash.insert(id, player);
    //qDebug() << "emit newPlayerConn";
    emit newPlayerConnected(player);
}

void ClientConnection::doLIST(PacketData* data)
{
    while (!data->atEnd())
    {

        qint32 id = data->nextInt();
        QString nick = data->nextString();
        qint32 score = data->nextInt();
        ConnectionPlayer* player = new ConnectionPlayer();
        player->setNick(nick);
        player->setScore(score);
        player->setPlayerId(id);
        connectionHash.insert(id, player);
        emit newPlayerConnected(player);
    }
}

void ClientConnection::doSTATE(PacketData* data)
{
	while (!data->atEnd())
	{
		qint32 id = data->nextInt();
		ConnectionPlayer* conn;
		bool hasPlayer = false;
		if (connectionHash.contains(id))
		{
			//qDebug() << "not me";
			conn = connectionHash.value(id);
			hasPlayer = true;
		} else if (id == getPlayerId())
		{
			//qDebug() << "oh its me";
			conn = this;
			hasPlayer = true;
		}

		qint32 isAlive = data->nextInt();

		if (isAlive == 1)
		{
			qreal x = data->nextReal();
			qreal y = data->nextReal();
			qint32 d1 = data->nextInt();
			qint32 d2 = data->nextInt();
			qint32 angle = data->nextInt();
			qint32 isReloading = data->nextInt();

			if (hasPlayer)
			{
				//if (conn != this) qDebug() << x << " x " << y;
				conn->setPosition(QPointF(x,y));
				conn->setDirs(d1,d2);
				conn->setAngle(angle);
				conn->setIsReloading(isReloading == 1);
			}
		}
		if (hasPlayer)
		{
			//qDebug() << "state is alive" << (isAlive);
			conn->setIsAlive(isAlive == 1);
		}
	}
}

void ClientConnection::doSHOOT(PacketData* data)
{
	qint32 id = data->nextInt();
	ConnectionPlayer* conn;

	if (connectionHash.contains(id))
	{
		conn = connectionHash.value(id);
		qreal x = data->nextReal();
		qreal y = data->nextReal();
		qint32 angle = data->nextInt();

		conn->fireGun(x,y,qreal(angle));
	}
}

void ClientConnection::doPING(PacketData* data)
{
    qint32 t = data->nextInt();
    PacketData* toSend = new PacketData();
    toSend->appendString("PONG");
    toSend->appendInt(t);
    sendPacket(toSend,false);
}

void ClientConnection::doDISCONNECT(PacketData* data)
{
    connectionHash.clear();
    disconnFromHost();
}

void ClientConnection::doQUIT(PacketData* data)
{
    qint32 id = data->nextInt();
    connectionHash.remove(id);
    emit playerDisconnected(id);
}
